<template>
  <div class="fx-rate-item" ref="rateItemDom" @click.stop="rateItemClick" @mousemove="rateItemMousemove">
    <span>
      <slot>{{ text }}</slot>
    </span>
    <span class="ac" :style="rateItemClipStyle">
      <slot>{{ text }}</slot>
    </span>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, ref, SetupContext, watch } from 'vue'

interface RateItemProps {
  rate: number;
  text: string;
  index: number;
  step: number;
  color: string;
  readonly: boolean;
}

export default defineComponent({
  name: 'fxRateItem',
  props: {
    rate: {
      type: Number as PropType<number>,
      default: 0
    },
    text: {
      type: String as PropType<string>,
      default: ''
    },
    index: {
      type: Number as PropType<number>,
      default: 0
    },
    step: {
      type: Number as PropType<number>,
      default: 0
    },
    color: {
      type: String as PropType<string>,
      default: ''
    },
    readonly: {
      type: Boolean as PropType<boolean>,
      default: false
    }
  },
  setup (props: RateItemProps, ctx: SetupContext) {
    const currentValue = ref<number>(props.rate - props.index)
    watch(() => props.rate, (val: number) => {
      currentValue.value = val - props.index
    })
    const rateItemDom = ref<HTMLElement>()

    const toStep = (value: number): number => {
      let dis: number
      if ((value % props.step) >= (props.step / 2)) {
        dis = Math.floor(value / props.step) * props.step + props.step
      } else {
        dis = Math.floor(value / props.step) * props.step
      }
      if (dis < 0) dis = 0
      return Number(dis.toFixed(1))
    }

    const rateItemClipStyle = computed(() => {
      if (!rateItemDom.value) return null
      const rect = rateItemDom.value.getBoundingClientRect()
      return {
        clip: `rect(0px, ${currentValue.value * rect.width}px, ${rect.height}px, 0px)`,
        color: props.color
      }
    })

    const rateItemMousemove = (ev: MouseEvent): void => {
      if (!rateItemDom.value || props.readonly) return
      const rect = rateItemDom.value.getBoundingClientRect()
      currentValue.value = toStep((ev.clientX - rect.left) / rect.width)
      ctx.emit('change', {
        value: currentValue.value,
        type: 'mousemove'
      })
    }

    const rateItemClick = (): void => {
      if (props.readonly) return
      ctx.emit('change', {
        value: currentValue.value,
        type: 'click'
      })
    }

    return {
      rateItemDom,
      currentValue,
      rateItemClipStyle,
      rateItemClick,
      rateItemMousemove
    }
  }
})
</script>
